package com.droid.network.exception;

import android.net.ParseException;

import com.google.gson.JsonParseException;

import org.json.JSONException;

import java.io.IOException;
import java.net.ConnectException;

import javax.net.ssl.SSLHandshakeException;

import retrofit2.HttpException;

/**
 * 网络异常处理
 *
 * @author zyc0617
 * @since 2019/7/9 17:07
 */
public class HttpExceptionHandle {

    private static final String TAG = "HttpExceptionHandle";

    private static final int UNAUTHORIZED = 401;
    private static final int FORBIDDEN = 403;
    private static final int NOT_FOUND = 404;
    private static final int REQUEST_TIMEOUT = 408;
    private static final int INTERNAL_SERVER_ERROR = 500;
    private static final int BAD_GATEWAY = 502;
    private static final int SERVICE_UNAVAILABLE = 503;
    private static final int GATEWAY_TIMEOUT = 504;
    private static final int SYNTAX_ERROR = 400;

    public static ResponseThrowable handleException(Throwable e) {
        //ResponseThrowable,根据状态码判定错误信息

        ResponseThrowable ex;
        if (e instanceof HttpException) {
            HttpException httpException = (HttpException) e;
            /**
             * 传入状态码，根据状态码判定错误信息
             */
            ex = new ResponseThrowable(e, ERROR.HTTP_ERROR);
            try {
                ex.errorBody = httpException.response().errorBody().string();
            } catch (IOException exc) {
                exc.printStackTrace();
            }
            switch (httpException.code()) {
                case UNAUTHORIZED:
                    ex.message = "未验证";
                    break;
                case FORBIDDEN:
                    ex.message = "服务禁止访问";
                    break;
                case NOT_FOUND:
                    ex.message = "服务不存在";
                    break;
                case REQUEST_TIMEOUT:
                    ex.message = "请求超时";
                    break;
                case GATEWAY_TIMEOUT:
                    ex.message = "网关超时";
                    break;
                case INTERNAL_SERVER_ERROR:
                    ex.message = "服务器内部错误";
                    break;
                case BAD_GATEWAY:
                    ex.message = "网关未响应";
                    break;
                case SERVICE_UNAVAILABLE:
                    ex.message = "服务不可访问";
                    break;
                case SYNTAX_ERROR:
                    ex.message = "服务器无法解析请求";
                    break;
                default:
                    ex.message = "网络错误";
                    break;
            }
            return ex;
        } else if (e instanceof JsonParseException
                || e instanceof JSONException
                || e instanceof ParseException) {
            ex = new ResponseThrowable(e, ERROR.PARSE_ERROR);
            ex.message = "解析错误";
            return ex;
        } else if (e instanceof ConnectException) {
            ex = new ResponseThrowable(e, ERROR.NETWORD_ERROR);
            ex.message = "连接失败";
            return ex;
        } else if (e instanceof SSLHandshakeException) {
            ex = new ResponseThrowable(e, ERROR.SSL_ERROR);
            ex.message = "证书验证失败";
            return ex;
        } else {
            ex = new ResponseThrowable(e, ERROR.UNKNOWN);
            ex.message = "未知错误";
            return ex;
        }
    }

    /**
     * 约定异常
     */
    public static class ERROR {
        /**
         * 协议出错
         */
        public static final int HTTP_ERROR = 1003;
        /**
         * 未知错误
         */
        public static final int UNKNOWN = 1000;
        /**
         * 解析错误
         */
        public static final int PARSE_ERROR = 1001;
        /**
         * 网络错误
         */
        public static final int NETWORD_ERROR = 1002;
        /**
         * 证书出错
         */
        public static final int SSL_ERROR = 1005;
    }

    /**
     * 统一异常类，便于处理
     */
    public static class ResponseThrowable extends Exception {
        private int code;
        private String message;
        private String errorBody;

        public ResponseThrowable(Throwable throwable, int code) {
            super(throwable);
            this.code = code;
        }

        public ResponseThrowable(Throwable cause, String message) {
            super(message, cause);
            this.message = message;
        }

        public ResponseThrowable(Throwable cause, int code, String message, String errorBody) {
            super(cause);
            this.code = code;
            this.message = message;
            this.errorBody = errorBody;
        }

        public int getCode() {
            return code;
        }

        public void setCode(int code) {
            this.code = code;
        }

        @Override
        public String getMessage() {
            return message;
        }

        public void setMessage(String message) {
            this.message = message;
        }

        public String getErrorBody() {
            return errorBody;
        }

        public void setErrorBody(String errorBody) {
            this.errorBody = errorBody;
        }
    }
}

